#include "warn_table.h"
#include "ui_warn_table.h"
#include <QDateTime>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>

warn_table::warn_table(QWidget *parent)
    : QWidget(parent), ui(new Ui::warn_table)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_StyledBackground); // 这句不加,样式表是加载不出来的
    initDatabase();                        // 初始化数据库
}

warn_table::~warn_table()
{
    if (m_db.isOpen())
    {
        m_db.close();
    }
    delete ui;
}

void warn_table::initDatabase()
{
    // 使用命名连接避免冲突
    m_db = QSqlDatabase::addDatabase("QSQLITE", "warning_db");
    m_db.setDatabaseName("warning.db");

    if (!m_db.open())
    {
        emit signalToForward("数据库打开失败: " + m_db.lastError().text());
        return;
    }

    // 创建报警信息表
    QSqlQuery query(m_db);
    QString createTableQuery = "CREATE TABLE IF NOT EXISTS warnings ("
                               "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                               "block_name TEXT, "
                               "position TEXT, "
                               "value TEXT, "
                               "start_time TEXT, "
                               "end_time TEXT, "
                               "status TEXT)";

    if (!query.exec(createTableQuery))
    {
        emit signalToForward("创建数据表失败: " + query.lastError().text());
    }
}

void warn_table::insertWarningToDB(WarningInfo &warning)
{
    QSqlQuery query(m_db);
    query.prepare("INSERT INTO warnings (block_name, position, value, start_time, status) "
                  "VALUES (?, ?, ?, ?, ?)");
    query.addBindValue(warning.blockName);
    query.addBindValue(warning.position);
    query.addBindValue(warning.value);
    query.addBindValue(warning.time);
    query.addBindValue("active"); // 报警状态为激活状态

    if (!query.exec())
    {
        emit signalToForward("插入报警记录失败: " + query.lastError().text());
        return;
    }

    // 获取插入记录的ID
    warning.id = query.lastInsertId().toInt();
}

void warn_table::updateWarningEndTime(const WarningInfo &warning)
{
    QSqlQuery query(m_db);
    query.prepare("UPDATE warnings SET end_time = ?, status = ? "
                  "WHERE block_name = ? AND position = ? AND value = ? AND status = 'active'");
    query.addBindValue(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
    query.addBindValue("resolved");
    query.addBindValue(warning.blockName);
    query.addBindValue(warning.position);
    query.addBindValue(warning.value);

    if (!query.exec())
    {
        emit signalToForward("更新报警结束时间失败: " + query.lastError().text());
    }
}

double warn_table::getThresholdForParameter(const QString &type, const QString &position)
{
    if (type == "温度")
    {
        // 判断是否为环境温度（柜内温度）
        if (position.contains("柜内"))
        {
            return m_tempLimit_hj;
        }
        // 否则认为是触头温度
        else
        {
            return m_tempLimit_cd;
        }
    }
    else if (type == "湿度")
    {
        return m_humLimit_hj;
    }
    else if (type == "超声波")
    {
        return m_dbLimit_cs;
    }
    else if (type == "暂态地电压")
    {
        return m_dbLimit_zt;
    }

    // 默认阈值
    return 100.0;
}

bool warn_table::processJsonCommand(const QString &jsonStr, QString *err)
{

    // 特殊处理 "EventRecord cleared" 消息
    if (jsonStr.contains("EventRecord cleared"))
    {
        // qDebug() << "warn_table: " << jsonStr;
        // qDebug() << "Clear all warnings";
        // 清空报警列表
        m_warningList.clear();

        // 更新表格显示
        ui->warningTableWidget->clearContents();
        ui->warningTableWidget->setRowCount(0);
        return true;
    }
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError)
    {
        emit signalToForward("JSON解析失败: " + error.errorString());
        return false;
    }

    QJsonObject root = doc.object();

    if (!root.contains("plugin_config") && !root.contains("plugin_data"))
    {
        emit signalToForward("JSON格式错误: 未找到plugin_datablock段");
        return false;
    }

    QString root_s = root.contains("plugin_config") ? "plugin_config" : "plugin_data";

    // 不再清空警告列表，而是创建一个新的临时列表来存储当前报警
    QList<WarningInfo> currentWarnings;

    QJsonObject datablock = root[root_s].toObject();
    QJsonArray blocks = datablock["blocks"].toArray();

    // 更新阈值
    QJsonValue tempLimitCdValue = datablock["tempLimit_cd"];
    if (tempLimitCdValue.isString() && !tempLimitCdValue.toString().isEmpty())
    {
        bool ok;
        double tempLimit = tempLimitCdValue.toString().toDouble(&ok);
        if (ok)
            m_tempLimit_cd = tempLimit;
    }
    else if (tempLimitCdValue.isDouble())
    {
        m_tempLimit_cd = tempLimitCdValue.toDouble();
    }

    QJsonValue tempLimitHjValue = datablock["tempLimit_hj"];
    if (tempLimitHjValue.isString() && !tempLimitHjValue.toString().isEmpty())
    {
        bool ok;
        double tempLimit = tempLimitHjValue.toString().toDouble(&ok);
        if (ok)
            m_tempLimit_hj = tempLimit;
    }
    else if (tempLimitHjValue.isDouble())
    {
        m_tempLimit_hj = tempLimitHjValue.toDouble();
    }

    QJsonValue humLimitHjValue = datablock["humLimit_hj"];
    if (humLimitHjValue.isString() && !humLimitHjValue.toString().isEmpty())
    {
        bool ok;
        double humLimit = humLimitHjValue.toString().toDouble(&ok);
        if (ok)
            m_humLimit_hj = humLimit;
    }
    else if (humLimitHjValue.isDouble())
    {
        m_humLimit_hj = humLimitHjValue.toDouble();
    }

    QJsonValue dbLimitCsValue = datablock["dbLImit_cs"]; // 注意这里是 dbLImit_cs (大小写不一致)
    if (dbLimitCsValue.isString() && !dbLimitCsValue.toString().isEmpty())
    {
        bool ok;
        double dbLimit = dbLimitCsValue.toString().toDouble(&ok);
        if (ok)
            m_dbLimit_cs = dbLimit;
    }
    else if (dbLimitCsValue.isDouble())
    {
        m_dbLimit_cs = dbLimitCsValue.toDouble();
    }

    QJsonValue dbLimitZtValue = datablock["dbLImit_zt"];
    if (dbLimitZtValue.isString() && !dbLimitZtValue.toString().isEmpty())
    {
        bool ok;
        double dbLimit = dbLimitZtValue.toString().toDouble(&ok);
        if (ok)
            m_dbLimit_zt = dbLimit;
    }
    else if (dbLimitZtValue.isDouble())
    {
        m_dbLimit_zt = dbLimitZtValue.toDouble();
    }

    // 获取当前时间作为报警时间
    QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

    // 直接在解析过程中筛选报警数据
    for (const QJsonValue &blockVal : blocks)
    {
        if (!blockVal.isObject())
            continue;

        QJsonObject blockObj = blockVal.toObject();
        QString blockName = blockObj["block_name"].toString();

        QJsonValue paramsValue = blockObj["parameters"];
        if (!paramsValue.isArray())
            continue;

        QJsonArray params = paramsValue.toArray();

        for (const QJsonValue &paramVal : params)
        {
            if (!paramVal.isObject())
                continue;

            QJsonObject paramObj = paramVal.toObject();
            QString type = paramObj["type"].toString();
            QString valueStr = paramObj["data"].toString();     // 使用data字段作为值
            QString position = paramObj["position"].toString(); // 获取位置信息

            // 处理所有类型的参数，不仅仅是温度和湿度
            // if (type != "温度" && type != "湿度")
            //     continue;

            // 根据类型和位置判断是否超出阈值
            bool isExceeded = false;
            double currentValue = 0;
            bool isNumber = false;

            currentValue = valueStr.toDouble(&isNumber);

            if (isNumber)
            {
                double threshold = getThresholdForParameter(type, position);
                isExceeded = currentValue > threshold;
            }

            // 如果超出阈值，则加入当前警告列表
            if (isExceeded)
            {
                WarningInfo warningInfo;
                warningInfo.blockName = blockName;
                warningInfo.position = position.isEmpty() ? "Unknown" : position;
                warningInfo.value = valueStr;
                warningInfo.type = type;
                warningInfo.time = currentTime; // 临时设置为当前时间，在updateWarningTable中会处理
                currentWarnings.append(warningInfo);
            }
        }
    }

    updateWarningTable(currentWarnings);
    return true;
}

void warn_table::updateWarningTable(const QList<WarningInfo> &currentWarnings)
{
    // 用于跟踪哪些现有项已经更新过
    QList<bool> updatedItems;
    for (int i = 0; i < m_warningList.size(); ++i)
    {
        updatedItems.append(false);
    }

    // 更新或添加新的报警项
    for (const WarningInfo &currentWarning : currentWarnings)
    {
        bool found = false;
        // 查找是否已存在相同的报警项（柜名、位置、类型相同）
        for (int i = 0; i < m_warningList.size(); ++i)
        {
            WarningInfo &existingWarning = m_warningList[i];
            if (existingWarning.blockName == currentWarning.blockName &&
                existingWarning.position == currentWarning.position &&
                existingWarning.type == currentWarning.type)
            {
                // 更新值，但保持原来的时间
                existingWarning.value = currentWarning.value;
                updatedItems[i] = true;
                found = true;
                break;
            }
        }

        // 如果是新报警项，则添加到列表中并插入数据库
        if (!found)
        {
            WarningInfo newWarning = currentWarning;
            newWarning.time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
            m_warningList.append(newWarning);
            updatedItems.append(true);
            insertWarningToDB(newWarning); // 插入新报警到数据库
        }
    }

    // 移除已消除的报警项（未被标记为更新的项）并更新数据库
    for (int i = m_warningList.size() - 1; i >= 0; --i)
    {
        if (!updatedItems[i])
        {
            updateWarningEndTime(m_warningList[i]); // 更新消除时间
            m_warningList.removeAt(i);
        }
    }

    // 更新表格显示
    ui->warningTableWidget->clearContents();
    ui->warningTableWidget->setRowCount(m_warningList.size());
    ui->warningTableWidget->setColumnCount(6); // 改为6列

    QStringList headers;
    headers << "序号" << "柜名" << "安装位置" << "数据类型" << "报警值" << "报警时间"; // 添加序号列
    ui->warningTableWidget->setHorizontalHeaderLabels(headers);
    ui->warningTableWidget->verticalHeader()->setVisible(false);
    // 填充表格数据
    for (int i = 0; i < m_warningList.size(); ++i)
    {
        const WarningInfo &info = m_warningList.at(i);

        // 创建表格项，添加序号项
        QTableWidgetItem *indexItem = new QTableWidgetItem(QString::number(i + 1)); // 序号从1开始
        QTableWidgetItem *blockNameItem = new QTableWidgetItem(info.blockName);
        QTableWidgetItem *positionItem = new QTableWidgetItem(info.position);
        QTableWidgetItem *typeItem = new QTableWidgetItem(info.type);
        // QTableWidgetItem *valueItem = new QTableWidgetItem(info.value);
        QString displayValue = info.value;
        double numericValue;
        bool isNumeric = false;
        numericValue = info.value.toDouble(&isNumeric);

        // 如果是数字，则格式化为显示一位小数
        if (isNumeric)
        {
            displayValue = QString::number(numericValue, 'f', 1);
        }

        QTableWidgetItem *valueItem = new QTableWidgetItem(displayValue);
        QTableWidgetItem *timeItem = new QTableWidgetItem(info.time);

        // 设置表格项不可编辑
        indexItem->setFlags(indexItem->flags() & ~Qt::ItemIsEditable);
        blockNameItem->setFlags(blockNameItem->flags() & ~Qt::ItemIsEditable);
        positionItem->setFlags(positionItem->flags() & ~Qt::ItemIsEditable);
        typeItem->setFlags(typeItem->flags() & ~Qt::ItemIsEditable);
        valueItem->setFlags(valueItem->flags() & ~Qt::ItemIsEditable);
        timeItem->setFlags(timeItem->flags() & ~Qt::ItemIsEditable);

        // 设置所有项内容居中对齐
        indexItem->setTextAlignment(Qt::AlignCenter);
        blockNameItem->setTextAlignment(Qt::AlignCenter);
        positionItem->setTextAlignment(Qt::AlignCenter);
        typeItem->setTextAlignment(Qt::AlignCenter);
        valueItem->setTextAlignment(Qt::AlignCenter);
        timeItem->setTextAlignment(Qt::AlignCenter);

        // 将项添加到表格中，调整列索引
        ui->warningTableWidget->setItem(i, 0, indexItem);     // 序号列
        ui->warningTableWidget->setItem(i, 1, blockNameItem); // 柜名列
        ui->warningTableWidget->setItem(i, 2, positionItem);  // 位置列
        ui->warningTableWidget->setItem(i, 3, typeItem);      // 类型列
        ui->warningTableWidget->setItem(i, 4, valueItem);     // 报警值列
        ui->warningTableWidget->setItem(i, 5, timeItem);      // 时间列
    }

    // 设置表格列宽自定义
    ui->warningTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    ui->warningTableWidget->setColumnWidth(0, 70); // 序号列
    // 让柜名列占据剩余空间
    ui->warningTableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
    // ui->warningTableWidget->setColumnWidth(1, 300); // 柜名列
    ui->warningTableWidget->setColumnWidth(2, 170); // 安装位置列
    ui->warningTableWidget->setColumnWidth(3, 100); // 数据类型列
    ui->warningTableWidget->setColumnWidth(4, 100); // 报警值列
    ui->warningTableWidget->setColumnWidth(5, 200); // 报警时间列

    ui->warningTableWidget->resizeRowsToContents();

    int rowCount = m_warningList.size();
    emit signalToForward(QString("warningTableSumChanged:%1").arg(rowCount));
}